package com.vois.jack.btmgr.devices.WLCommonBleDev;

import android.bluetooth.BluetoothGatt;
import android.os.Bundle;
import android.os.Message;
import android.util.Log;

import com.vois.jack.btmgr.blebase.BleAction;
import com.vois.jack.btmgr.blebase.BleConstant;
import com.vois.jack.btmgr.blebase.BleDevCommonMsg;
import com.vois.jack.btmgr.classicbase.BtRecorderInterface;
import com.vois.jack.btmgr.common.DeviceRecorderControlInterface;
import com.vois.jack.btmgr.util.Logger;

import java.util.UUID;

public abstract class DefaultWLBleMediaDevice extends DefaultWLBleDevice {
    private static final String TAG = DefaultWLBleMediaDevice.class.getName();
    public final static int OPUS_SINGLE_PACK = 0x01;
    public final static int SBC_PARAM_PACK = 0x02;
    public final static int OPUS_COMPO_PACK = 0x03;

    private final Logger logger = Logger.getLogger(DefaultWLBleMediaDevice.class);
    protected static final UUID STREAM_UUID = UUID.fromString("00004103-0000-1000-8000-00805F9B34FB");
    protected byte[] mediaParams;
    protected int supportMediaStreamType;
    protected ResultCallback startRecorderCb;
    protected ResultCallback stopRecorderCb;

    public DefaultWLBleMediaDevice() {
        super();
        setFullConnectTryTimes(10);
        CommnadWrapper commnadWrapper = new CommnadWrapper();
        commnadWrapper.handlerClass = DefaultWLBleMediaDevice.class;
        commnadWrapper.methodName = "onStartRecordRes";
        registerCommandHandler(WLBleCommand.BLE_CMD_START_RECORD.getValue(), commnadWrapper);
        commnadWrapper = new CommnadWrapper();
        commnadWrapper.handlerClass = DefaultWLBleMediaDevice.class;
        commnadWrapper.methodName = "onStopRecordRes";
        registerCommandHandler(WLBleCommand.BLE_CMD_STOP_RECORD.getValue(), commnadWrapper);
        commnadWrapper = new CommnadWrapper();
        commnadWrapper.handlerClass = DefaultWLBleMediaDevice.class;
        commnadWrapper.methodName = "onMediaFeatureRet";
        registerCommandHandler(WLBleCommand.BLE_CMD_QUERY_MEDIA_FEATURE.getValue(), commnadWrapper);
    }

    public boolean onMediaFeatureRet(int cmdLen, byte[] cmdData) {

        boolean supportMedia = (cmdData[0] != 0x00);
        supportMediaStreamType = cmdData[0];
        Log.d(TAG, "onMediaFeatureRet: " + supportMedia);
        if (supportMedia) {
            if (cmdLen > 1) {
                mediaParams = new byte[cmdLen - 1];
                System.arraycopy(cmdData, 1, mediaParams, 0, cmdLen - 1);
            }
        }

        return true;
    }

    public boolean onStartRecordRes(int cmdLen, byte[] cmdData) {
        int result = cmdData[0] & 0xFF;

        if (startRecorderCb != null) {
            startRecorderCb.onResult(result == 1);
            startRecorderCb = null;
        }
        return true;
    }

    public boolean onStopRecordRes(int cmdLen, byte[] cmdData) {
        int result = cmdData[0] & 0xFF;

        if (stopRecorderCb != null) {
            stopRecorderCb.onResult(result == 1);
            stopRecorderCb = null;
        }

        return true;
    }

    @Override
    public void onCharacteristiChanged(UUID serviceUUID, UUID characteristicUUID, byte[] data) {
        super.onCharacteristiChanged(serviceUUID, characteristicUUID, data);
        if (characteristicUUID.equals(STREAM_UUID)) {
            onStreamDataProcess(data);
        }
    }

    abstract protected void onStreamDataProcess(byte[] data);
    abstract protected int getRequestMaxMtu();

    @Override
    public boolean startRecorder(ResultCallback callback) {
        startRecorderCb = callback;
        Log.d(TAG, "startRecorder: ");
        sendCommand(WLBleCommand.BLE_CMD_START_RECORD, null, 0);

        return true;
    }

    @Override
    public void stopRecorder(ResultCallback callback) {
        if (startRecorderCb != null) {
            startRecorderCb.onResult(false);
        }
        Log.d(TAG, "stopRecorder: ");
        stopRecorderCb = callback;
        sendCommand(WLBleCommand.BLE_CMD_STOP_RECORD, null, 0);
    }

    @Override
    public int getSampleRate() {
        return 16000;
    }

    @Override
    public void onReady() {
        super.onReady();
        Log.d(TAG, "onReady: ");
        enableCharacteristicNotification(SERVICE_UUID, STREAM_UUID, true, NOTIFY_TYPE, new BleAction.BleActionCallback() {
            @Override
            public void onActionResult(int status, Bundle result) {
                if (status == BluetoothGatt.GATT_SUCCESS) {
                    negotiateMTU(getRequestMaxMtu(), new BleAction.BleActionCallback() {
                        @Override
                        public void onActionResult(int status, Bundle result) {
                            Log.d(TAG, "getRequestMaxMtu onActionResult: " + status);
                            if (status == BluetoothGatt.GATT_SUCCESS) {
                                setCurrentMTU(getRequestMaxMtu());
                            }else {
                                setCurrentMTU(23);
                            }

                            sendCommand(WLBleCommand.BLE_CMD_QUERY_MEDIA_FEATURE, null, 0);
                        }
                    });
                }
            }
        });
    }
}
